#ifndef GAMETABLE_HPP
#define GAMETABLE_HPP

#include "Deck.h"
#include "Pile.h"
#include <string>
#include <iostream>

const int MAX_LEGIT_MOVES = 6;

const char LEGIT_MOVES[MAX_LEGIT_MOVES][2] = {
		{ 'D', 'H' }, //Deck to Hand
		{ 'H', 'S' }, //Hand to Stack
		{ 'H', 'C' }, //Hand to Column
		{ 'S', 'C' }, //Stack to Column
		{ 'C', 'S' }, //Column to stack
		{ '7', 'S' }, //Devil to Stack
};

//Coordinates for each type of pile-ish objects.
//------------------------------
const int DEVILS_XPOS = 72;
const int DEVILS_YPOS = 1;

const int DECK_XPOS = 1;
const int DECK_YPOS = 11;

const int HAND_XPOS = 1;
const int HAND_YPOS = 18;

const int COLUMNS_XPOS = 12;
const int COLUMNS_YPOS = 8;
const int COLUMNS_SPACE = 8;

const int STACKS_XPOS = 11;
const int STACKS_YPOS = 1;
const int STACKS_SPACE = 7;
//----------------------------


//Coordinates and string for the wrapper around stacks and columns ID.
const std::string WRAPPER = "[ ]";
const int WRAPPER_STACKS_XPOS = 12;
const int WRAPPER_STACKS_YPOS = 0;
const int WRAPPER_COLUMNS_XPOS = 13;
const int WRAPPER_COLUMNS_YPOS = 7;

//The coordinates and strings for each objects.
const std::string S_STACKS = "(S)tacks:";
const int S_STACKS_XPOS = 1;
const int S_STACKS_YPOS = 0;

const std::string S_COLUMNS = "(C)olumns:";
const int S_COLUMNS_XPOS = 1;
const int S_COLUMNS_YPOS = 7;

const std::string S_DECK = "(D)eck";
const int S_DECK_XPOS = 1;
const int S_DECK_YPOS = 10;

const std::string S_HAND = "(H)and";
const int S_HAND_XPOS = 1;
const int S_HAND_YPOS = 17;

const std::string S_DEVILS = "(7)Devils";
const int S_DEVILS_XPOS = 70;
const int S_DEVILS_YPOS = 0;

struct gameTable
{
	deck gameDeck;
	deck gameHand;

	pile gameColumns[7];
	pile gameDevils;
	pile gameStacks[8];
};

//Initialization and Display prototypes.
void Initialize(gameTable& gt);
void Display(const gameTable& gt);

//We spread around the joy, taking from the deck and placing where it belongs on the board.
//Fills the devil, column and hand area.
void Populate(gameTable& gt);

//The prototype for the only action that GameTable can actually do, Transfert something from one place to another.
template <typename Origin, typename Destination>
void Transfert(Origin& o, Destination& d, bool flipUp = false);

//This is where magic happen, where you get to transfert a card from one pile to another.
//Keep in mind pile means anything, be it deck, hand, columns, stack, devils, this is why templates are used here.
template <typename Origin, typename Destination>
void Transfert(Origin& o, Destination& d, bool flipUp)
{
	if (o.nb != 0)
	{
		o.nb -= 1;
		d.cards[d.nb] = o.cards[o.nb];
		if (flipUp)
		{
			Flip(d.cards[d.nb], true);
		}
		d.nb += 1;
	}
}

//Determines if a move is valid before calling Transfert()
bool IsValid(char origin[1], char destination[1]);


//Display related prototypes.
void ClearScreen(const char& ch = char(255));
void PlaceString(const std::string& str, int xPos, int yPos);
void FillScreen(const char& ch, int xPos, int yPos, int width = 1, int height = 1);

#endif